import {BaseService} from '../core/BaseService';
import {DatabaseManager} from '../core/DatabaseManager';
import {getEntityMetadata} from './entity.decorators';
import Database from "better-sqlite3";
import {EntityClass} from "../types";

/**
 * 服务装饰器，用于创建与特定实体关联的服务类
 * 装饰后的类将自动注入数据库连接和实体信息
 *
 * @param entity 实体类
 *
 * @example
 * ```typescript
 * @Service(User)
 * class UserService extends BaseService<User> {
 *   // 自定义方法...
 * }
 * ```
 */
export function Service<T extends BaseService<any>>(entity: EntityClass) {
  return function (target: any) {
    // 创建原型方法来获取数据库管理器
    target.prototype.getDatabaseManager = function (): DatabaseManager {
      const entityMetadata = getEntityMetadata(entity);
      if (!entityMetadata) {
        throw new Error(`获取实体类 ${entity.name} 元数据失败，请确保在使用服务前已定义实体类`);
      }
      return entityMetadata.db;
    };

    // 创建原型方法来获取数据库
    target.prototype.getDatabase = function () {
      return this.getDatabaseManager().getDatabase();
    };

    // 覆盖构造函数
    const originalConstructor = target;

    function newConstructor(...args: any[]) {
      const entityMetadata = getEntityMetadata(entity);
      if (!entityMetadata) {
        throw new Error(`获取实体类 ${entity.name} 元数据失败，请确保在使用服务前已定义实体类`);
      }

      // 创建服务实例
      const db = entityMetadata.db.getDatabase();
      const instance = (args.length > 0 && !(args[0] instanceof Database)) ? new originalConstructor(...args, db, entity) : new originalConstructor(db, entity);

      // 使用Object.defineProperties来复制BaseService的原型方法
      const propertyDescriptors: PropertyDescriptorMap = {};
      Object.getOwnPropertyNames(BaseService.prototype).forEach(name => {
        if (name !== 'constructor' && typeof (BaseService.prototype as any)[name] === 'function') {
          const descriptor = Object.getOwnPropertyDescriptor(BaseService.prototype, name);
          if (descriptor) {
            propertyDescriptors[name] = descriptor;
          }
        }
      });
      Object.defineProperties(instance, propertyDescriptors);

      // 设置必要的属性
      // instance.db = db;
      // instance.entityClass = entity;
      // instance.tableInfo = entity.getTableInfo();

      return instance;
    }

    // 复制原型和静态属性
    newConstructor.prototype = originalConstructor.prototype;
    Object.setPrototypeOf(newConstructor, originalConstructor);

    // 替换构造函数
    return newConstructor as any;
  };
}
